#include "SDL.h"
#include "SDL_ttf.h"

#include <string>
#include <iostream>
using namespace std;

constexpr int WindowWidth = 1024;
constexpr int WindowHeight = 720;
constexpr int FontSize = 16;
constexpr int NumFontSize = 10;
constexpr int Padding = 4;
constexpr int Col = WindowWidth / (FontSize + NumFontSize * 4);
constexpr int Row = WindowHeight / (FontSize + NumFontSize + Padding);

void DrawOnePage(SDL_Renderer* renderer, int row, TTF_Font* imageFont, TTF_Font* numFont) {
    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
    SDL_RenderClear(renderer);
    for (int i = 0; i < Row; i++) {
        for (int j = 0; j < Col; j++) {
            uint32_t idx = Col * (i + row) + j;
            auto surface = TTF_RenderGlyph_Solid(imageFont, (Uint16)(idx), {255, 255, 255, 255});
            if (!surface) continue;
            SDL_Texture* texture= SDL_CreateTextureFromSurface(renderer, surface);
            SDL_FreeSurface(surface);
            SDL_Rect rect = {j * (FontSize + NumFontSize * 4), i * (FontSize + NumFontSize + Padding), FontSize, FontSize};
            SDL_RenderCopy(renderer, texture, nullptr, &rect);
            SDL_DestroyTexture(texture);

            string num = to_string(idx);
            surface = TTF_RenderUTF8_Solid(numFont, num.c_str(), {100, 100, 100, 255});
            texture = SDL_CreateTextureFromSurface(renderer, surface);
            rect.w = surface->w;
            rect.h = surface->h;
            SDL_FreeSurface(surface);
            rect.y += FontSize + Padding / 2;
            SDL_RenderCopy(renderer, texture, nullptr, &rect);
            SDL_DestroyTexture(texture);
        }
    }
    SDL_RenderPresent(renderer);
}


int main(int argc, char** argv) {
    SDL_Init(SDL_INIT_EVERYTHING);
    TTF_Init();

    atexit([](){
            TTF_Quit();
            SDL_Quit();
           });

    if (argc != 2) {
        cout << "please give me a font filename" << endl;
        return 1;
    }

    string filename = argv[1];
    TTF_Font* font = TTF_OpenFont(filename.c_str(), FontSize);
    TTF_Font* numFont = TTF_OpenFont(filename.c_str(), NumFontSize);
    if (!font) {
        cout << filename << " not exists" << endl;
        return 2;
    }

    SDL_Window* window = SDL_CreateWindow(
                            "show font",
                            SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
                            WindowWidth, WindowHeight,
                            SDL_WINDOW_SHOWN
                        );
    SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, 0);

    SDL_Event e;
    bool shouldClose = false;

    int row = 0;

    DrawOnePage(renderer, row, font, numFont);

    while (!shouldClose) {
        while (SDL_PollEvent(&e)) {
            if (e.type == SDL_QUIT)
                shouldClose = true;
            if (e.type == SDL_KEYDOWN) {
                if (e.key.keysym.sym == SDLK_h) {
                    row = std::max(0, row - Row);
                    DrawOnePage(renderer, row, font, numFont);
                }
                if (e.key.keysym.sym == SDLK_l) {
                    row += Row;
                    DrawOnePage(renderer, row, font, numFont);
                }
            }
        }
    }

    TTF_CloseFont(numFont);
    TTF_CloseFont(font);
    SDL_DestroyWindow(window);
    SDL_DestroyRenderer(renderer);
    return 0;
}
